﻿using _01单例模式;
using _01观察者模式;
using _01适配器模式;
using _02中介者模式;
using _02原型模式;
using _02装饰器模式;
using _03桥接模式;
using _03模板方法;
using _03简单工厂;
using _04工厂模式;
using _04组合模式;
using _04责任链模式;
using _05外观模式;
using _05迭代器模式;
using _06享元模式;
using _06命令模式;
using _06抽象工厂;
using _07代理模式;
using _07状态模式;
using System;


namespace _23种设计模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("<<<<<<<<<<========================创建型=====================================>>>>>>>>>>>>>>>>>>>>>>>!");
            Console.WriteLine("------------1.单例测试-----------------------------------!");
            {
                var a1 = SingleFirst.GetInstance();
                var a2 = SingleFirst.GetInstance();
                Console.WriteLine($"a1 和 a2 是同一实例：{ object.ReferenceEquals(a1, a2)}");
                ;
                var b1 = SingleSecond.GetInstance();
                var b2 = SingleSecond.GetInstance();
                Console.WriteLine($"b1 和 b2 是同一实例：{ object.ReferenceEquals(a1, a2)}");
                var c1 = SingleThrid.GetInstance();
                var c2 = SingleThrid.GetInstance();
                Console.WriteLine($"c1 和 c2 是同一实例：{ object.ReferenceEquals(a1, a2)}");
            }

            Console.WriteLine("------------2.原型测试-----------------------------------!");
            {
                var a1 = ProteType.GetInstance();
                var a2 = ProteType.GetInstance();
                Console.WriteLine($"a1 和 a2 是同一实例：{ object.ReferenceEquals(a1, a2)}");
            }
            Console.WriteLine("------------3.简单工厂测试-----------------------------------!");
            {
                MouseFachtory mouseFachtory = new MouseFachtory();
                var mouse1 = mouseFachtory.CreateMouse("dell");
                var mouse2 = mouseFachtory.CreateMouse("dell");
                var mouse3 = mouseFachtory.CreateMouse("dell");
                var mouse4 = mouseFachtory.CreateMouse("hp");
                var mouse5 = mouseFachtory.CreateMouse("hp");
                var mouse6 = mouseFachtory.CreateMouse("lenovo");
                mouse1.Print();
                mouse2.Print();
                mouse3.Print();
                mouse4.Print();
                mouse5.Print();
                mouse6.Print();
            }

            Console.WriteLine("------------4.工厂模式测试-----------------------------------!");
            {
                //生产一个戴尔鼠标
                MouseFactory dellMouseFactory = new DellMouseFactroy();
                _04工厂模式.Mouse dellMouse = dellMouseFactory.CreateMouse();
                dellMouse.Print();

                //生产一个惠普鼠标
                MouseFactory hpMouseFactory = new HpMouseFactory();
                _04工厂模式.Mouse hpMouse = hpMouseFactory.CreateMouse();
                hpMouse.Print();

                //生产一个联想鼠标
                LenovoMouseFactory lenovoMouseFactory = new LenovoMouseFactory ();
                _04工厂模式.Mouse lenovoMouse = lenovoMouseFactory.CreateMouse();
                lenovoMouse.Print();
            }
            Console.WriteLine("------------5.抽象工厂测试-----------------------------------!");
            {
                //生产一个戴尔鼠标/键盘
                PcFactory dellFactory = new DellPcFactroy();
                _06抽象工厂.Mouse dellMouse = dellFactory.CreateMouse();
                Keybo dellKeybo = dellFactory.CreateKeybo();
                dellMouse.Print();
                dellKeybo.Print();

                //生产一个惠普鼠标/键盘
                PcFactory hpFactory = new HpPcFactory();
                _06抽象工厂.Mouse hpMouse = hpFactory.CreateMouse();
                Keybo hpKeybo = hpFactory.CreateKeybo();
                hpMouse.Print();
                hpKeybo.Print();

                //生产一个联想鼠标/键盘
                LenovoPcFactory lenovoFactory = new LenovoPcFactory();
                _06抽象工厂.Mouse lenovoMouse = hpFactory.CreateMouse();
                Keybo lenovoKeybo = hpFactory.CreateKeybo();
                lenovoMouse.Print();
                lenovoKeybo.Print();
            }
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("<<<<<<<<<<========================结构型=====================================>>>>>>>>>>>!");
            Console.WriteLine("------------1.适配器模式-----------------------------------!");
            {
                //继承 既满足现有的规范调用，又没有修改RedisHelper  
                //类适配器模式
                IHelper helper = new RedisHelperInherit();
                helper.Add<Program>();
                helper.Delete<Program>();
                helper.Update<Program>();
                helper.Query<Program>();
            }
            {
                //组合 既满足现有的规范调用，又没有修改RedisHelper 
                //对象适配器
                IHelper helper = new RedisHelperObject();
                helper.Add<Program>();
                helper.Delete<Program>();
                helper.Update<Program>();
                helper.Query<Program>();
            }
            Console.WriteLine("------------2.装饰器模式-----------------------------------!");
            {
                AbstractStudent student = new StudentVip()
                {
                    Id = 666,
                    Name = "加菲猫"
                };
               // student.Study();
                //BaseStudentDecorator decorator = new BaseStudentDecorator(student);
                //AbstractStudent decorator = new BaseStudentDecorator(student);//里氏替换
                student = new BaseStudentDecorator(student);//引用替换一下
                student = new StudentHomeworkDecorator(student);
                student = new StudentVideoDecorator(student);
                student.Study();
            }
            Console.WriteLine("------------3.桥接模式-----------------------------------!");
            {
                Shape circle = new Circle();
                IColor blue = new Blue();
                circle.SetColor(blue);//设置颜色
                circle.Draw();//画图

                Shape triangle = new Triangle();
                triangle.SetColor(blue);
                triangle.Draw();
            }
            Console.WriteLine("------------4.组合模式-----------------------------------!");
            {
                Component DepartA = new Dept("A总公司");
                Component DepartAX = new Dept("AX部门");
                Component DepartAY = new Dept("AY部门");
                Component DepartAX1 = new Dept("AX1子部门");
                Component DepartAX2 = new Dept("AX2子部门");
                Component Ae1 = new Employee("公司直属员工1");
                Component AXe1 = new Employee("AX部门员工1");
                Component AX1e1 = new Employee("AX1部门员工1");
                Component AX1e2 = new Employee("AX1部门员工2");
                Component AYe1 = new Employee("AY部门员工1");
                Component AYe2 = new Employee("AY部门员工2");
                DepartA.Add(Ae1);
                DepartA.Add(DepartAX);
                DepartA.Add(DepartAY);
                DepartAX.Add(AXe1);
                DepartAX.Add(DepartAX1);
                DepartAX.Add(DepartAX2);
                DepartAX1.Add(AX1e1);
                DepartAX1.Add(AX1e2);
                DepartAY.Add(AYe1);
                DepartAY.Add(AYe2);
                //遍历总公司
                DepartA.DisPlay(1);
            }
            Console.WriteLine("------------5.外观模式-----------------------------------!");
            {
                Computer computer = new Computer();
                //开机
                computer.Start();
                Console.WriteLine();
                //关机
                computer.Shutdown();
            }
            Console.WriteLine("------------6.享元模式-----------------------------------!");
            {
                CarFactory carFactory = new CarFactory();

                //小头爸爸开蓝色的车
                Driver d1 = new Driver("小头爸爸");
                Car c1 = carFactory.GetCar("蓝色");
                c1.Use(d1);

                //扁头妈妈开蓝色的车
                Driver d2 = new Driver("扁头妈妈");
                Car c2 = carFactory.GetCar("蓝色");
                c2.Use(d2);

                if (c1.Equals(c2))
                {
                    Console.WriteLine("小头爸爸和扁头妈妈开的是同一辆车");
                }

                //车库没有白色的车，就new一辆白色的车
                Driver d3 = new Driver("大头儿子");
                Car c3 = carFactory.GetCar("白色");
                c3.Use(d3);
            }

            Console.WriteLine("------------7.代理模式-----------------------------------!");
            {
                //因为不能直接访问到真实对象所以我们不能直接new ShyBoy()去送礼物。
                //代码中使用的是代理对象
                Friend friend = new Friend();
                friend.GiveGift();
            }
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("<<<<<<<<<<========================行为型=====================================>>>>>>>>>>>!");
            Console.WriteLine("------------1.观察者模式-----------------------------------!");
            {
                MiShu mishu = new MiShu();
                //新建同事 观察者角色
                Observer tongshi1 = new StockObserver("巴菲特", mishu);
                Observer tongshi2 = new NBAObserver("麦迪", mishu);
                //秘书小妹要知道哪些同事要通知（主题要知道所有订阅了自己的观察者）
                mishu.Add(tongshi1);
                mishu.Add(tongshi2);
                //主题状态更改了
                mishu.SubjectState = "老板回来了！";
                //调用主题的通知方法
                mishu.Notify();
            }

            Console.WriteLine("------------2.中介者模式-----------------------------------!");
            {
                AbstractCardPlayer a = new PlayerA() { MoneyCount = 20 };
                AbstractCardPlayer b = new PlayerB() { MoneyCount = 20 };
                AbstractMediator mediator = new Mediator(a, b);
                //玩家a赢了玩家b 5元
                Console.WriteLine("a赢了b5元");
                a.ChangeCount(5, mediator);
                Console.WriteLine($"玩家a现在有{a.MoneyCount}元");
                Console.WriteLine($"玩家b现在有{b.MoneyCount}元");
                //玩家b赢了玩家a 10元
                Console.WriteLine("b赢了a10元");
                b.ChangeCount(10, mediator);
                Console.WriteLine($"玩家a现在有{a.MoneyCount}元");
                Console.WriteLine($"玩家b现在有{b.MoneyCount}元");
            
            }
            Console.WriteLine("------------3.模板模式-----------------------------------!");
            {
                //玩恐龙快打
                Game klkdGame = new KLKDGame();
                klkdGame.Play();
                Console.WriteLine();

                //玩三国无双
                Game sgwsGame = new SGWSGame();
                sgwsGame.Play();

            }

            Console.WriteLine("------------4.责任链模式---------------------------------!");
            {
                //1. 有人要请假
                LeaveRequest myRequest1 = new LeaveRequest()
                {
                    name = "小明",
                    leaveDays = 6
                };
                LeaveRequest myRequest2 = new LeaveRequest()
                {
                    name = "小王",
                    leaveDays = 2
                };
                LeaveRequest myRequest3 = new LeaveRequest()
                {
                    name = "小放",
                    leaveDays = 15
                };
                LeaveRequest myRequest4 = new LeaveRequest()
                {
                    name = "张三",
                    leaveDays = 35
                };

                //2. 请假相关的责任链
                LeaderHandler1 handler1 = new LeaderHandler1();
                LeaderHandler2 handler2 = new LeaderHandler2();
                LeaderHandler3 handler3 = new LeaderHandler3();
                handler1.NextHandler = handler2;
                handler2.NextHandler = handler3;

                //3.进行请假处理
                handler1.HandleRequest(myRequest1);
                handler1.HandleRequest(myRequest2);
                handler1.HandleRequest(myRequest3);
                handler1.HandleRequest(myRequest4);
            }
            Console.WriteLine("------------5.迭代器模式---------------------------------!");
            {
                //聚合对象添加数据
                IAggregate<string> ag = new ConcreteAggregate<string>();
                ag.Add("001");
                ag.Add("002");
                ag.Add("003");
                ag.Add("004");
                //获取对应的迭代器
                Iterator<string> it = ag.GetIterator();
                //输出数据
                Console.WriteLine($"第一个元素为:{it.First()}");
                Console.WriteLine("剩下的元素为：");
                while (it.HasNext())
                {
                    Console.WriteLine(it.Next());
                }
            }
            Console.WriteLine("------------6.命令模式---------------------------------!");
            {
                // 初始化Receiver、Invoke和Command
                Receiver r = new Receiver();
                Command c = new ConcreteCommand(r);
                Invoke i = new Invoke(c);

                // 院领导发出命令
                i.ExecuteCommand();
            }
            Console.WriteLine("------------7.状态模式---------------------------------!");
            {
                // 开一个新的账户
                Account account = new Account("张三");

                // 进行交易
                // 存钱
                account.Deposit(1000.0);
                account.Deposit(200.0);
                account.Deposit(600.0);

                // 付利息
                account.PayInterest();

                // 取钱
                account.Withdraw(2000.00);
                account.Withdraw(500.00);
            }
            Console.ReadKey();
            Console.ReadLine();
        }
    }
}
